"""
异常处理模块
负责处理系统各种异常情况
"""

import logging
import time
from enum import Enum
from typing import Callable, Dict, List
import threading


class ExceptionType(Enum):
    """异常类型枚举"""
    AUDIO_INPUT_ERROR = "audio_input_error"         # 音频输入异常
    NETWORK_ERROR = "network_error"                 # 网络通信异常
    ROBOT_EXECUTION_ERROR = "robot_execution_error" # 机器人执行异常
    SYSTEM_RESOURCE_ERROR = "system_resource_error" # 系统资源异常


class ExceptionHandler:
    """
    异常处理器
    负责处理系统各种异常情况
    """
    
    def __init__(self):
        """初始化异常处理器"""
        self.exception_listeners = []  # 异常监听器列表
        self.exception_history = []    # 异常历史记录
        self.retry_counts = {}         # 重试计数
        self.max_retry_count = 3       # 最大重试次数
        self.lock = threading.Lock()
        
        # 设置日志
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        self.logger = logging.getLogger(__name__)
        
    def handle_exception(self, exception_type: ExceptionType, message: str, 
                        callback: Callable = None, auto_retry: bool = True):
        """
        处理异常
        
        Args:
            exception_type: 异常类型
            message: 异常信息
            callback: 回调函数
            auto_retry: 是否自动重试
        """
        with self.lock:
            exception_record = {
                'type': exception_type.value,
                'message': message,
                'timestamp': time.time(),
                'handled': False
            }
            
            # 添加到异常历史
            self.exception_history.append(exception_record)
            
            # 保持历史记录在合理范围内
            if len(self.exception_history) > 100:
                self.exception_history = self.exception_history[-50:]
                
            # 记录日志
            self.logger.error(f"异常 [{exception_type.value}]: {message}")
            
        # 根据异常类型采取不同的处理策略
        if exception_type == ExceptionType.AUDIO_INPUT_ERROR:
            self._handle_audio_input_error(message, callback, auto_retry)
        elif exception_type == ExceptionType.NETWORK_ERROR:
            self._handle_network_error(message, callback, auto_retry)
        elif exception_type == ExceptionType.ROBOT_EXECUTION_ERROR:
            self._handle_robot_execution_error(message, callback, auto_retry)
        elif exception_type == ExceptionType.SYSTEM_RESOURCE_ERROR:
            self._handle_system_resource_error(message, callback, auto_retry)
            
        # 通知监听器
        self._notify_exception_listeners(exception_type, message)
        
    def _handle_audio_input_error(self, message: str, callback: Callable, auto_retry: bool):
        """
        处理音频输入异常
        
        Args:
            message: 异常信息
            callback: 回调函数
            auto_retry: 是否自动重试
        """
        # 音频输入异常处理策略:
        # 1. 自动重试短时异常
        # 2. 降级运行（使用默认音频输入或静音）
        # 3. 用户提示
        
        exception_key = f"{ExceptionType.AUDIO_INPUT_ERROR.value}_{message}"
        
        if auto_retry and self._should_retry(exception_key):
            self.logger.info("尝试自动恢复音频输入...")
            self._increment_retry_count(exception_key)
            
            # 这里应该实现实际的恢复逻辑
            time.sleep(1)  # 模拟恢复时间
            
            # 恢复成功后重置计数
            self._reset_retry_count(exception_key)
            
            if callback:
                callback("audio_recovered")
        else:
            # 无法自动恢复，需要用户干预
            self.logger.warning("音频输入异常无法自动恢复，请检查设备")
            if callback:
                callback("audio_error_manual")
                
    def _handle_network_error(self, message: str, callback: Callable, auto_retry: bool):
        """
        处理网络通信异常
        
        Args:
            message: 异常信息
            callback: 回调函数
            auto_retry: 是否自动重试
        """
        # 网络通信异常处理策略:
        # 1. 自动重试短时异常
        # 2. 降级运行（使用本地预设动作）
        # 3. 安全停止（紧急情况下）
        # 4. 用户提示
        
        exception_key = f"{ExceptionType.NETWORK_ERROR.value}_{message}"
        
        if auto_retry and self._should_retry(exception_key):
            self.logger.info("尝试重新连接机器人...")
            self._increment_retry_count(exception_key)
            
            # 这里应该实现实际的重连逻辑
            time.sleep(2)  # 模拟重连时间
            
            # 重连成功后重置计数
            self._reset_retry_count(exception_key)
            
            if callback:
                callback("network_reconnected")
        else:
            # 无法自动恢复，进入降级模式
            self.logger.warning("网络连接异常，进入降级模式")
            if callback:
                callback("network_degraded")
                
    def _handle_robot_execution_error(self, message: str, callback: Callable, auto_retry: bool):
        """
        处理机器人执行异常
        
        Args:
            message: 异常信息
            callback: 回调函数
            auto_retry: 是否自动重试
        """
        # 机器人执行异常处理策略:
        # 1. 自动重试短时异常
        # 2. 降级运行（简化动作）
        # 3. 安全停止（紧急情况下）
        # 4. 用户提示
        
        exception_key = f"{ExceptionType.ROBOT_EXECUTION_ERROR.value}_{message}"
        
        if auto_retry and self._should_retry(exception_key):
            self.logger.info("尝试重新执行动作...")
            self._increment_retry_count(exception_key)
            
            # 这里应该实现实际的重试逻辑
            time.sleep(0.5)  # 模拟重试时间
            
            # 重试成功后重置计数
            self._reset_retry_count(exception_key)
            
            if callback:
                callback("action_retry_success")
        else:
            # 无法自动恢复，安全停止
            self.logger.error("机器人执行异常，执行安全停止")
            if callback:
                callback("robot_safety_stop")
                
    def _handle_system_resource_error(self, message: str, callback: Callable, auto_retry: bool):
        """
        处理系统资源异常
        
        Args:
            message: 异常信息
            callback: 回调函数
            auto_retry: 是否自动重试
        """
        # 系统资源异常处理策略:
        # 1. 自动重试短时异常
        # 2. 降级运行（降低处理质量）
        # 3. 安全停止（紧急情况下）
        # 4. 用户提示
        
        self.logger.warning(f"系统资源不足: {message}")
        
        # 尝试释放资源
        self._release_resources()
        
        if callback:
            callback("resource_warning")
            
    def _release_resources(self):
        """释放系统资源"""
        # 这里应该实现实际的资源释放逻辑
        # 例如清理缓存、关闭不必要的连接等
        self.logger.info("正在释放系统资源...")
        time.sleep(0.5)
        self.logger.info("资源释放完成")
        
    def _should_retry(self, exception_key: str) -> bool:
        """
        判断是否应该重试
        
        Args:
            exception_key: 异常键
            
        Returns:
            bool: 是否应该重试
        """
        retry_count = self.retry_counts.get(exception_key, 0)
        return retry_count < self.max_retry_count
        
    def _increment_retry_count(self, exception_key: str):
        """
        增加重试计数
        
        Args:
            exception_key: 异常键
        """
        self.retry_counts[exception_key] = self.retry_counts.get(exception_key, 0) + 1
        
    def _reset_retry_count(self, exception_key: str):
        """
        重置重试计数
        
        Args:
            exception_key: 异常键
        """
        if exception_key in self.retry_counts:
            del self.retry_counts[exception_key]
            
    def add_exception_listener(self, listener: Callable[[ExceptionType, str], None]):
        """
        添加异常监听器
        
        Args:
            listener: 异常监听回调函数
        """
        if listener not in self.exception_listeners:
            self.exception_listeners.append(listener)
            
    def remove_exception_listener(self, listener: Callable[[ExceptionType, str], None]):
        """
        移除异常监听器
        
        Args:
            listener: 要移除的监听器
        """
        if listener in self.exception_listeners:
            self.exception_listeners.remove(listener)
            
    def _notify_exception_listeners(self, exception_type: ExceptionType, message: str):
        """
        通知异常监听器
        
        Args:
            exception_type: 异常类型
            message: 异常信息
        """
        for listener in self.exception_listeners:
            try:
                listener(exception_type, message)
            except Exception as e:
                self.logger.error(f"异常监听器调用错误: {e}")
                
    def get_exception_history(self) -> List[Dict]:
        """
        获取异常历史记录
        
        Returns:
            List[Dict]: 异常历史记录列表
        """
        return self.exception_history.copy()


# 全局异常处理器实例
exception_handler = ExceptionHandler()


def get_exception_handler() -> ExceptionHandler:
    """
    获取全局异常处理器实例
    
    Returns:
        ExceptionHandler: 异常处理器实例
    """
    return exception_handler